'use strict';

layui.extend({
  menusearch: 'admin/menusearch',
  pagetabs  : 'admin/pagetabs'
}).define(['choose', 'entity', 'helper', 'Http', 'pagetabs', 'store', 'menusearch'], function(exports) {
  var $ = layui.jquery;
  var setter = layui.setter;
  var entity = layui.entity;
  var helper = layui.helper;
  var Http = layui.Http;
  var view = layui.view;
  var store = layui.store;
  var layer = layui.layer;
  var debug = layui.hint();
  // plugins
  var choose = layui.choose;
  var search = layui.menusearch;

  var MODULE_NAME = 'gwzh';
  var FILTER_PAGETABS = 'layadmin-pagetabs';

  var isTop = top === self;
  var _layui = isTop ? layui : top.layui;
  var _view = isTop ? view : _layui.view;
  var _layer = isTop ? layer : _layui.layer;
  var _pagetabs = isTop ? layui.pagetabs : _layui.pagetabs;

  var ClassName = {
    APP_SHRINK  : 'layadmin-layout-shrink',
    APP_MOBILE  : 'layadmin-layout-mobile',
    ICON        : 'layui-icon',
    ICON_SHRINK : 'layui-icon-shrink-right',
    ICON_SPREAD : 'layui-icon-spread-left',
    SHOW        : 'layui-show',
    THIS        : 'layui-this',
    CONTEXT_MENU: 'layadmin-pagetabs-contextmenu',
    BACKDROP    : 'layadmin-pagetabs-backdrop'
  };

  var Selector = {
    APP        : setter.app,
    FLEX       : '#layadmin-flexible',
    SIDEMENU   : '#layadmin-side',
    TABSPAGE   : '#' + FILTER_PAGETABS,
    CONTEXTMENU: '#' + ClassName.CONTEXT_MENU,
    BACKDROP   : '#' + ClassName.BACKDROP
  };

  var $win = $(window);
  var $body = $('body');
  var $app = $(Selector.APP);
  var $flex = $(Selector.FLEX);

  var admin = {
    v     : '2.0.0', // require(package.json).version
    // xss 转义
    escape: function(html) {
      return String(html || '').replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&amp;')
        .replace(/</g, '&lt;').replace(/>/g, '&gt;')
        .replace(/'/g, '&#39;').replace(/"/g, '&quot;');
    },

    // 屏幕类型
    screen: function(isTop) {
      var width = isTop ? top.innerWidth : $win.width();

      if (width >= 1200) {
        return 3;
      } else if (width >= 992) {
        return 2;
      } else if (width >= 768) {
        return 1;
      } else {
        return 0;
      }
    },

    // 事件监听
    $on: function(eventType, callback) {
      return _layui.onevent.call(this, MODULE_NAME, eventType, callback);
    },

    // 事件响应
    $emit: function(eventType, params) {
      _layui.event.call(this, MODULE_NAME, eventType, params);
    },

    // 侧边伸缩
    sideFlexible: function(status) {
      // var screen = this.screen();
      // // 手机模式
      // if (screen < 2) {
      //   $app.addClass(ClassName.APP_MOBILE);
      // } else {
      //   $app.removeClass(ClassName.APP_MOBILE);
      // }

      // 切换伸缩按钮和侧边菜单的状态
      if (status === 'spread') { // 如果展开状态则收起
        $app.removeClass(ClassName.APP_SHRINK);
        $flex.find('.layui-icon').removeClass(ClassName.ICON_SPREAD).addClass(ClassName.ICON_SHRINK);
      } else {
        $app.addClass(ClassName.APP_SHRINK);
        $flex.find('.layui-icon').removeClass(ClassName.ICON_SHRINK).addClass(ClassName.ICON_SPREAD);
      }

      this.$emit('side-flexible', status);
    },

    routes         : [],
    ROUTE_KEY      : 'routes',
    ROUTE_MAX_VALUE: 4,
    initRoute      : function() {
      var routes = store.get(this.ROUTE_KEY);
      this.routes = $.isArray(routes) ? routes : [];
      this.$emit('on-route-change', this.routes);
    },
    addRoute: function(option) {
      var handleUnique = function(array) {
        if (!$.isArray(array)) return [];

        array.push(option);

        var i = 0; var len = array.length; var target;
        var ret = [];

        while (i < len) {
          var item = array[i];
          item.id === option.id ? target = option : ret.push(item);
          i++;
        }
        target && ret.push(target);
        return ret;
      };

      this.routes = handleUnique(this.routes);
      this.routes.splice(0, this.routes.length - this.ROUTE_MAX_VALUE); // 删除旧的路由
      store.set(this.ROUTE_KEY, this.routes);
      this.$emit('on-route-change', this.routes);
    },
    delRoute: function(index) {
      if (index >= this.routes.length) return;
      this.routes.splice(index, 1);
      store.set(this.ROUTE_KEY, this.routes);
      this.$emit('on-route-change', this.routes);
    }
  };

  var events = admin.events = {
    more: function() {
      _view.popupRight({
        id     : 'layadmin-popup-setter',
        success: function(layero, index) {
          var JAVA_ENV = {
            dev    : 'development',
            prod   : 'production',
            test   : 'test',
            release: 'release'
          };
          view('#' + this.id).render('version', { v: admin.v, env: JAVA_ENV[window.$$env] || '' });
        }
      });
    },
    logout: function() {
      view.alert({
        skin   : 'layadmin-view-popup-logout',
        content: '确定退出？',
        yes    : function() {
          window.location.href = (window.$$path || '').concat('/login/logout.htm');
        }
      }, 'warning');
    },
    back: function() {
      window.history && $.isFunction(window.history.back) && window.history.back();
    },
    flexible: function() {
      admin.sideFlexible($app.hasClass(ClassName.APP_SHRINK) ? 'spread' : '');
    },
    sso: function() {
      var api = new Http({
        type: 'post',
        url : '/login/requestTicket'
      });

      api.fetch(function(response) {
        var ticket = response && response.ticket;
        var url = response && response.url;

        if (ticket && url) {
          window.location.href = url + '?Ticket=' + encodeURIComponent(ticket);
        }
      }, false);
    }
  };

  /**
 * @description 动态配置 select 选项
 * @param {Object} option 配置
 * @param {string|Object} option.el css 选择器
 * @param {string|Object[]} option.data 数据
 * @param {string} [option.textKey="name"] 展现所需要的关键字
 * @param {string} [option.valueKey="code"] 真正返回所需要的值
 * @param {string} option.defaultValue 默认选中值，即选择框默认选项
 * @param {string|boolean} option.placeholder 占位信息
 *
 * @param {Function} [callback=$.noop] 回调函数
 */
  admin.setSelect = function(option) {
    var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : $.noop;

    // 配置参数类型检测
    var type = $.type(option);
    if (type !== 'object') return;

    // 配置合并
    var _option = {
      el          : null,
      data        : '',
      textKey     : 'name',
      valueKey    : 'code',
      defaultValue: '',
      placeholder : ''
    };
    $.extend(_option, option);

    // 配置中容器检测
    var $el = $(_option.el);
    if ($el.length) {
      $el.html(''); // 清空原生中的select选项
    } else {
      debug.error('无法找到指定目标');
      return;
    }

    // 配置中数据检测
    var data = null;
    var dataType = $.type(option.data);

    if (dataType === 'array') {
      data = option.data;
    } else if (dataType === 'string') {
      try {
        data = option.data ? JSON.parse(option.data) : [];
      } catch (e) {
        debug.error('解析错误', e);
      }
    }
    if (!$.isArray(data)) {
      debug.error('数据无法转成数组类型');
      return;
    }

    // 析构配置
    var textKey = _option.textKey;
    var valueKey = _option.valueKey;
    var defaultValue = _option.defaultValue;
    var placeholder = $el.attr('placeholder') || _option.placeholder;

    // 配置中占位信息检测

    var placeholderHtml = '';
    var placeholderType = $.type(placeholder);
    if (placeholderType === 'boolean') {
      placeholderHtml = placeholder ? '<option value></option>' : '';
    } else {
      placeholderHtml = '<option value>' + (placeholder || '') + '</option>';
    }

    var optgroupHtml = '';
    var hasOptgroup = false;
    for (var i = 0; i < data.length; i++) {
      var item = data[i];
      var optionHtml = '';
      if (item.children && item.children.length) {
        hasOptgroup = true;
        optgroupHtml += '<optgroup label="' + item[textKey] + '">';
        for (var j = 0; j < item.children.length; j++) {
          var subItem = item.children[j];
          optionHtml += '<option title="' + subItem[textKey] + '" value="' + subItem[valueKey] + '"' + (subItem[valueKey] === defaultValue ? ' selected' : '') + '>' + subItem[textKey] + '</option>';
        }
        optgroupHtml += optionHtml;
        optgroupHtml += '</optgroup>';
      } else {
        optionHtml += '<option title="' + item[textKey] + '" value="' + item[valueKey] + '"' + (item[valueKey] === defaultValue ? ' selected' : '') + '>' + item[textKey] + '</option>';
        optgroupHtml += optionHtml;
      }
    }
    // layui中的一个bug（占位没有，后面选择会失效，所以出现optgroup默认添加占位）
    if (!placeholderHtml && hasOptgroup) {
      placeholderHtml = '<option value></option>';
    }

    $el.html(placeholderHtml + optgroupHtml);
    $.isFunction(callback) && callback();

    return this;
  };

  /**
   * @description 转化get请求的url
   * @param {string} url 链接地址
   * @param {Object} option 链接地址的携带参数
   * @return {string}
   * @example
   *util.transUrl('xxx/xxx', {name: 'jack', id: 1, death: true})
  * result: 'xxx/xxx?name=jack&id=1&death=true'
  */
  admin.transUrl = helper.parseURLParam;

  // 比较时间大小
  admin.compareDate = function(d1, d2, option) {
    if (option === '>=') {
      return new Date(d1.replace(/-/g, '\/')) >= new Date(d2.replace(/-/g, '\/'));
    } else if (option === '>') {
      return new Date(d1.replace(/-/g, '\/')) > new Date(d2.replace(/-/g, '\/'));
    } else if (option === '==') {
      return new Date(d1.replace(/-/g, '\/')) === new Date(d2.replace(/-/g, '\/'));
    }
  };

  // 代理接口
  $.extend(admin, helper);
  window.App = window.App || (function() {
    return { util: helper };
  })();
  // 表单赋值
  admin.setEntity = entity.set.bind(entity);
  // 表单取值
  admin.getEntity = entity.get.bind(entity);
  // 表单检测
  admin.checkEntity = entity.check.bind(entity);
  // 单复选框赋值
  admin.setChoose = admin.choose = choose.set.bind(choose);
  // 单复选框取值
  admin.getChoose = admin.getSelected = choose.get.bind(choose);
  // 项目基础弹窗
  admin.popup = _view.popup.bind(_view);
  // 项目右侧弹窗
  admin.popupRight = _view.popupRight.bind(_view);
  // 项目错误弹窗
  admin.error = _view.error.bind(_view);
  // 项目提示弹窗
  admin.alert = _view.alert.bind(_view);
  // 项目询问弹窗
  admin.confirm = _view.confirm.bind(_view);
  // 项目通知弹窗
  admin.broadcast = _view.broadcast.bind(_view);
  // 项目展示信息弹窗
  admin.msg = _layer.msg.bind(_layer);

  $(function() {
    var $search = $('#menusearch');

    var fetchSearchMenu = function() {
      $search.data('state', 'fetching');
      new Http({
        url    : '/v1/searchMenu',
        data   : { menuName: '' },
        success: function(response) {
          var data = $.isArray(response && response.data) ? response.data : [];
          search.render('#menusearch', data);
          $search.data('state', 'done');
        }
      }, false).fetch();
    };

    $search.length && fetchSearchMenu();
    $search.on('click', function() {
      var $this = $(this);
      var $up = $this.next();
      if (!$up[0]) {
        view.error('正在加载数据，请稍后...');
        if ($this.data('state') !== 'fetching') {
          fetchSearchMenu();
        }
      }
    });

    // 窗口变动
    var _ = layui.data.resizeSystem = function() {
      layer.closeAll('tips');
      _.lock || setTimeout(function() {
        delete _.lock;
      }, 100);
      _.lock = true;
    };
    $win.on('resize', layui.data.resizeSystem);
  });

  // 绑定页面事件
  $body.on('mouseenter', '*[lay-tips]', function() {
    var $this = $(this);
    var tips = $this.attr('lay-tips');
    var offset = $this.attr('lay-offset');
    var direction = +$this.attr('lay-direction') || 1;

    if (admin.screen(true) > 2) {
      var index = layer.tips(tips, this, {
        tips   : direction,
        time   : -1,
        success: function success(layero) {
          var deffer = ($this.height() - layero.height()) / 2;
          $.isNumeric(offset) && (deffer += offset);

          if (direction === 1 || direction === 3) {
            deffer && layero.css('margin-left', deffer);
          } else if (direction === 2 || direction === 4) {
            deffer && layero.css('margin-top', deffer);
          }
        }
      });

      $this.data('tips', index);
    }
  });

  $body.on('mouseleave', '*[lay-tips]', function() {
    admin.screen() > 2 ? layer.close($(this).data('tips')) : layer.closeAll();
  });

  $body.on('click', '*[layadmin-event]', function() {
    var $this = $(this);
    var eventKey = $this.attr('layadmin-event');
    events[eventKey] && events[eventKey].call(this);
  });

  $body.on('click', '*[lay-href]', function() {
    var $this = $(this);
    var $cite = $this.find('cite');
    var url = $this.attr('lay-href');

    if (!url) return;

    layer.close($this.data('tips'));

    var ret = {
      url : $this.attr('lay-href'),
      id  : $this.attr('lay-id') || $this.data('id'),
      text: $this.attr('lay-text') || ($cite.length ? $this.find('cite').text() : $this.text()),
      tips: $this.data('wholeLabel')
    };
    admin.addRoute($.extend({}, ret, { date: layui.util.toDateString() }));
    ret.id === 'main' ? _pagetabs.change('main') : _pagetabs.add(ret);
  });

  exports(MODULE_NAME, admin);
});
